package com.sunlake.spring.main.model.orders.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sunlake.spring.main.common.enums.orders.OrdersPaymentMethod;
import com.sunlake.spring.main.common.enums.orders.OrdersPaymentStatus;
import com.sunlake.spring.main.common.enums.orders.OrdersStatus;
import com.sunlake.spring.main.common.enums.orders.OrdersTypeEnum;
import com.sunlake.spring.main.common.response.R;
import com.sunlake.spring.main.model.account.service.AccountService;
import com.sunlake.spring.main.model.account.dto.FreezeBalanceDTO;
import com.sunlake.spring.main.model.account.vo.AccountBalanceVO;
import com.sunlake.spring.main.model.course.vo.CourseDetailVO;
import com.sunlake.spring.main.model.orders.dto.OrdersCreateDTO;
import com.sunlake.spring.main.model.orders.dto.PayOrderDTO;
import com.sunlake.spring.main.model.orders.dto.PayOrderResponseDTO;
import com.sunlake.spring.main.model.orders.dto.OrdersQueryDTO;
import com.sunlake.spring.main.model.orders.mapper.OrdersMapper;
import com.sunlake.spring.main.model.orders.po.OrdersPO;
import com.sunlake.spring.main.model.orders.service.OrdersService;
import com.sunlake.spring.main.model.orders.vo.OrdersQueryVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @author liuhanzhi49
 */
@Service
public class OrdersServiceImpl implements OrdersService {
    @Autowired
    private OrdersMapper ordersMapper;
    
    @Autowired
    private AccountService accountService;
    
    @Autowired
    private com.sunlake.spring.main.model.course.service.CourseService courseService;

    @Override
    @Transactional
    public R<String> createOrder(OrdersCreateDTO ordersCreateDTO, Long userId) {
        try {
            // 1. 生成订单号
            String orderNo = generateOrderNo();
            
            // 2. 获取商品信息
            BigDecimal totalAmount;
            String itemTitle = "";
            
            if (ordersCreateDTO.getType() == OrdersTypeEnum.COURSE) {
                // 获取课程信息
                R<CourseDetailVO> courseResult = courseService.getCourseDetail(ordersCreateDTO.getItemId().longValue());
                if (courseResult.getCode() != 200 || courseResult.getData() == null) {
                    return R.error(404, "课程不存在");
                }
                CourseDetailVO course = courseResult.getData();
                totalAmount = course.getPrice();
                itemTitle = course.getTitle();
            } else {
                return R.error(400, "不支持的订单类型");
            }
            
            // 3. 创建订单
            OrdersPO order = new OrdersPO();
            order.setOrderNo(orderNo);
            order.setType(ordersCreateDTO.getType().toString());
            order.setItemId(ordersCreateDTO.getItemId());
            order.setItemTitle(itemTitle);
            order.setTotalAmount(totalAmount);
            order.setActualAmount(totalAmount); // 暂时不考虑优惠券
            order.setDiscountAmount(BigDecimal.ZERO);
            order.setStatus(OrdersStatus.PENDING.toString());
            order.setPaymentStatus(OrdersPaymentStatus.PENDING.toString());
            order.setRemark(ordersCreateDTO.getRemark());
            
            // 设置用户ID
            order.setUserId(userId.intValue());
            
            // 设置订单过期时间（30分钟）
            order.setExpiredAt(LocalDateTime.now().plusMinutes(30));
            
            int result = ordersMapper.insert(order);
            if (result > 0) {
                return R.ok(200, "订单创建成功，请尽快支付", orderNo);
            } else {
                return R.error(500, "订单创建失败");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(500, "订单创建失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional
    public R<PayOrderResponseDTO> payOrder(String orderNo, PayOrderDTO payOrderDTO, Long userId) {
        try {
            // 1. 查询订单
            OrdersPO order = ordersMapper.selectByOrderNo(orderNo);
            if (order == null) {
                return R.error(404, "订单不存在");
            }
            
            // 2. 验证订单状态
            if (OrdersPaymentStatus.PAID.toString().equals(order.getPaymentStatus())) {
                return R.error(400, "订单已支付");
            }
            
            if (OrdersStatus.CANCELLED.toString().equals(order.getStatus())) {
                return R.error(400, "订单已取消");
            }
            
            if (order.getExpiredAt() != null && order.getExpiredAt().isBefore(LocalDateTime.now())) {
                return R.error(400, "订单已过期");
            }
            
            // 3. 根据支付方式处理
            if (OrdersPaymentMethod.BALANCE.toString().equals(payOrderDTO.getPaymentMethod().toString())) {
                return processBalancePayment(order, userId);
            } else if (OrdersPaymentMethod.ALIPAY.toString().equals(payOrderDTO.getPaymentMethod().toString())) {
                return processAlipayPayment(order, payOrderDTO);
            } else {
                return R.error(400, "不支持的支付方式");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            return R.error(500, "支付失败：" + e.getMessage());
        }
    }
    
    /**
     * 处理余额支付
     */
    private R<PayOrderResponseDTO> processBalancePayment(OrdersPO order, Long userId) {
        // 1. 检查用户余额
        R<?> accountBalanceResult = accountService.getAccountBalance(userId);
        if (accountBalanceResult.getSuccess() == null || !accountBalanceResult.getSuccess() || accountBalanceResult.getData() == null) {
            return R.error(500, "获取用户余额失败");
        }
        
        // 从AccountBalanceVO中获取余额
        AccountBalanceVO balanceVO = (AccountBalanceVO) accountBalanceResult.getData();
        BigDecimal balance = BigDecimal.valueOf(balanceVO.getBalance());
        
        if (balance.compareTo(order.getActualAmount()) < 0) {
            return R.error(400, "余额不足");
        }
        
        // 2. 冻结余额
        FreezeBalanceDTO freezeDTO = new FreezeBalanceDTO();
        freezeDTO.setAmount(order.getActualAmount());
        freezeDTO.setTransactionNo(order.getOrderNo());
        freezeDTO.setBusinessDesc("支付订单：" + order.getOrderNo());
        R<?> freezeResult = accountService.freezeBalance(userId, freezeDTO);
        if (freezeResult.getSuccess() == null || !freezeResult.getSuccess()) {
            return R.error(500, "余额冻结失败");
        }
        
        // 3. 更新订单状态
        order.setPaymentStatus(OrdersPaymentStatus.PAID.toString());
        order.setStatus(OrdersStatus.COMPLETED.toString());
        order.setPaymentMethod(OrdersPaymentMethod.BALANCE.toString());
        order.setPaidAt(LocalDateTime.now());
        ordersMapper.updateByPrimaryKey(order);
        
        // 4. 扣除余额 - 使用payWithBalance方法
        boolean payResult = accountService.payWithBalance(userId, order.getOrderNo(), order.getActualAmount());
        if (!payResult) {
            return R.error(500, "余额扣除失败");
        }
        
        // 5. 返回支付结果
        PayOrderResponseDTO response = PayOrderResponseDTO.balancePay(order.getOrderNo());
        return R.ok(200, "支付成功", response);
    }
    
    /**
     * 处理支付宝支付
     */
    private R<PayOrderResponseDTO> processAlipayPayment(OrdersPO order, PayOrderDTO payOrderDTO) {
        // 这里应该调用支付宝API生成支付链接
        // 暂时返回模拟的支付链接
        String paymentUrl = "https://openapi.alipay.com/gateway.do?order_no=" + order.getOrderNo();
        
        // 更新订单支付方式
        order.setPaymentMethod(OrdersPaymentMethod.ALIPAY.toString());
        ordersMapper.updateByPrimaryKey(order);
        
        PayOrderResponseDTO response = PayOrderResponseDTO.thirdPartyPay(order.getOrderNo(), paymentUrl);
        return R.ok(200, "支付链接生成成功", response);
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        return "ORD" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }

    @Override
    public R<PageInfo<OrdersQueryVO>> getMyOrders(OrdersQueryDTO queryDTO, Long userId) {
        // 分页设置
        Long page = (long) (queryDTO.getPage() != null ? queryDTO.getPage() : 1);
        Integer limit = queryDTO.getLimit() != null ? queryDTO.getLimit() : 10;
        PageHelper.startPage(Math.toIntExact(page), limit);

        // 调用mapper查询
        List<OrdersPO> ordersPOList = ordersMapper.selectByUserIdAndConditions(
                userId,
                queryDTO.getType() != null ? queryDTO.getType().toString() : null,
                queryDTO.getStatus() != null ? queryDTO.getStatus().toString() : null,
                null, // paymentStatus
                null, // startTime
                null  // endTime
        );

        // 转换PO到VO
        List<OrdersQueryVO> ordersVOList = ordersPOList.stream().map(po -> {
            OrdersQueryVO vo = new OrdersQueryVO();
            // 基本字段转换
            vo.setId(po.getId() != null ? po.getId().longValue() : null);
            vo.setOrderNo(po.getOrderNo());
            vo.setUserId(po.getUserId() != null ? po.getUserId().longValue() : null);
            vo.setType(po.getType());
            vo.setItemId(po.getItemId() != null ? po.getItemId().longValue() : null);
            vo.setItemTitle(po.getItemTitle());
            vo.setAmount(po.getActualAmount()); // 使用实际支付金额作为amount
            vo.setOriginalAmount(po.getTotalAmount()); // 总金额作为originalAmount
            vo.setDiscountAmount(po.getDiscountAmount());
            vo.setPaymentStatus(po.getPaymentStatus());
            vo.setStatus(po.getStatus());
            vo.setRemark(po.getRemark());
            vo.setPaymentMethod(po.getPaymentMethod());

            // 日期格式化
            if (po.getCreatedAt() != null) {
                vo.setCreatedAt(po.getCreatedAt().toString());
            }
            if (po.getUpdatedAt() != null) {
                vo.setUpdatedAt(po.getUpdatedAt().toString());
            }
            if (po.getPaidAt() != null) {
                vo.setPayTime(po.getPaidAt().toString());
            }

            // 其他不存在于PO的字段可以根据实际业务需求设置默认值或从其他地方获取
            vo.setCouponId(null);
            vo.setTransactionId(null);
            vo.setRefundAmount(BigDecimal.ZERO);
            vo.setRefundTime(null);
            vo.setRefundReason(null);
            vo.setRefundNo(null);
            vo.setValidStartDate(null);
            vo.setValidEndDate(null);

            return vo;
        }).collect(Collectors.toList());

        // 包装分页结果
        return R.ok(200,"查询成功",new PageInfo<>(ordersVOList));
    }

    @Override
    public R<OrdersQueryVO> getOrder(String orderNo) {
        OrdersPO ordersPO = ordersMapper.selectByOrderNo(orderNo);
        if (ordersPO == null) {
            return R.error(404, "订单不存在");
        }
        OrdersQueryVO vo = new OrdersQueryVO();
        BeanUtils.copyProperties(ordersPO, vo);
        return R.ok(200,"查询成功",vo);
    }
}